#include "all.h"

int cnt{0};
libco::Mutex mu;

const int SCHEDULE_COUNTS = 20;

void func2() {
    libco::Mutex::Lock lock(mu);
    ++cnt;
    LIBCO_LOG_INFO << "func2 count =" << cnt;
    if (cnt == 2 * SCHEDULE_COUNTS) {
        std::cout << "finished\n";
    }
}

void func1() {
    libco::Mutex::Lock lock(mu);
    ++cnt;
    LIBCO_LOG_INFO << "func1 count =" << cnt;
    if (cnt == 2 * SCHEDULE_COUNTS) {
        std::cout << "finished\n";
    }
    co_func(func2);
}

void test_co_func(int a, int b, std::string c) {
    LIBCO_LOG << "test_co_func " << a << b << c;
}

void test_grab() {
    for(int i=0; i<64; ++i) {
        co_func([](){
            LIBCO_LOG << "get from stealing";
        });
    }
}

std::optional<char> init() {
    // auto tmp = std::thread(libco::Monitor::GetThis);
    libco::Monitor::GetThis();
    return std::nullopt;
}

auto tmp = init();

int main() {
    // sleep(5);
    std::cout << "Main Begin\n";
    libco::Coroutine::ptr co(new libco::Coroutine([](){
        LIBCO_LOG_DEBUG << "I am the first worker, ready to yield";
        co_yield
        LIBCO_LOG_DEBUG << "I am the first worker, back from resume";
    }));
    co_func(co);
    for(int i=0; i<SCHEDULE_COUNTS; ++i) {
        co_func(func1);
    }
    // sleep(5);
    co_func(test_grab);
    co_func(test_co_func, 1, 2, "3");
    sleep(5);
    std::cout << "Main End, count = " << cnt << "\n";
}